package cn.jinjimi.app.main.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import cn.jinjimi.base.util.StringUtils;
import cn.jinjimi.base.util.ViewUtils;
import cn.jinjimi.app.R;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * Created by Roy
 * 暂时只是兼容单行滚动以及2行向上滚动的TextView，后续兼容多行以及向下滚动的方法
 * Date: 16/7/26
 */
public class VerticalSwitchTextView extends TextView implements View.OnClickListener {
    private static final int DEFAULT_SWITCH_DURATION = 500;
    private static final int DEFAULT_IDLE_DURATION = 2000;
    private static final int DEFAULT_MAX_TEXT_SIZE = 13; //sp

    private List<String> lists;//会循环显示的文本内容
    private String maxLenStr = "";//循环的文本中最长的一段

    private int contentSize;
    private String outStr;//当前滑出的文本内容
    private String inStr;//当前滑入的文本内容

    private int currentIndex = 0;//当前显示到第几个文本

    private int switchDuaration = DEFAULT_SWITCH_DURATION;//切换时间
    private int idleDuaration = DEFAULT_IDLE_DURATION;//间隔时间
    private int maxTextSize;
    private int switchOrientation = 0;
    private boolean singleLine = true;

    private float currentAnimatedValue = 0.0f;
    private ValueAnimator animator;

    private float textBaseY;//文本显示的baseline
    private float textBaseY2;//显示2行的文本baseline

    private int mWidth;
    private int mHeight;
    private int paddingLeft = 0;

    private float fontHeight; // 字高
    private float fontLeading;// 行间距

    private Paint mPaint;

    //回调接口，用来通知调用者控件当前的状态
    public VerticalSwitchTextViewCbInterface cbInterface;

    public VerticalSwitchTextView(Context context) {
        this(context, null);
    }

    public VerticalSwitchTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerticalSwitchTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.VerticalSwitchTextView);
        try {
            switchDuaration = array.getInt(R.styleable.VerticalSwitchTextView_switchDuaration, DEFAULT_SWITCH_DURATION);
            idleDuaration = array.getInt(R.styleable.VerticalSwitchTextView_idleDuaration, DEFAULT_IDLE_DURATION);
            switchOrientation = array.getInt(R.styleable.VerticalSwitchTextView_switchOrientation, 0);
            maxTextSize = array.getDimensionPixelSize(R.styleable.VerticalSwitchTextView_switchMaxTextSize, ViewUtils.sp2px(context, DEFAULT_MAX_TEXT_SIZE));
            singleLine = array.getBoolean(R.styleable.VerticalSwitchTextView_switchSingleLine, true);
        } finally {
            array.recycle();
        }
        init();
    }

    private void init() {
        setOnClickListener(this);

        mPaint = getPaint();
        mPaint.setColor(getCurrentTextColor());
    }

    private void initAnimator() {
        animator = ValueAnimator.ofFloat(0f, 1f).setDuration(switchDuaration);
        animator.setStartDelay(idleDuaration);
        animator.addUpdateListener(new WeakAnimatorUpdateListener(this));
        animator.addListener(new WeakAnimatorListener(this));
    }

    private static class WeakAnimatorUpdateListener implements ValueAnimator.AnimatorUpdateListener {

        private WeakReference<VerticalSwitchTextView> mVerticalSwitchTextView;

        public WeakAnimatorUpdateListener(VerticalSwitchTextView verticalSwitchTextView) {
            this.mVerticalSwitchTextView = new WeakReference<>(verticalSwitchTextView);
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            VerticalSwitchTextView verticalSwitchTextView = mVerticalSwitchTextView.get();
            if (verticalSwitchTextView != null) {
                verticalSwitchTextView.currentAnimatedValue = (float) animation.getAnimatedValue();
                if (verticalSwitchTextView.currentAnimatedValue < 1.0f) {
                    verticalSwitchTextView.invalidate();
                }
            } else {
                animation.removeAllListeners();
                animation.cancel();
            }

        }
    }

    private static class WeakAnimatorListener implements Animator.AnimatorListener {

        private WeakReference<VerticalSwitchTextView> mVerticalSwitchTextView;

        public WeakAnimatorListener(VerticalSwitchTextView verticalSwitchTextView) {
            this.mVerticalSwitchTextView = new WeakReference<>(verticalSwitchTextView);
        }

        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            VerticalSwitchTextView verticalSwitchTextView = mVerticalSwitchTextView.get();
            if (verticalSwitchTextView != null) {
                verticalSwitchTextView.currentIndex = (++verticalSwitchTextView.currentIndex) % verticalSwitchTextView.contentSize;
                if (verticalSwitchTextView.cbInterface != null) {
                    verticalSwitchTextView.cbInterface.showNext(verticalSwitchTextView.currentIndex);
                }
                verticalSwitchTextView.outStr = verticalSwitchTextView.lists.get(verticalSwitchTextView.currentIndex);
                verticalSwitchTextView.inStr = verticalSwitchTextView.lists.get((verticalSwitchTextView.currentIndex + 1) % verticalSwitchTextView.contentSize);

                verticalSwitchTextView.animator.setStartDelay(verticalSwitchTextView.idleDuaration);
                verticalSwitchTextView.animator.start();
            } else {
                animation.removeAllListeners();
                animation.cancel();
            }
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    }

    /**
     * 设置循环显示的文本内容
     *
     * @param contents 内容list
     */
    public void setTextContent(List<String> contents) {
        if (contents == null || contents.size() == 0)
            return;

        if (isEquale(contents))
            return;

        lists = contents;
        contentSize = lists.size();

        outStr = lists.get(0);
        inStr = contentSize > 1 ? lists.get(1) : lists.get(0);

        if (animator != null) {
            animator.removeAllListeners();
            animator.cancel();
            animator.end();
            animator = null;
        }

        if (mWidth > 0)
            calcul();

        currentAnimatedValue = 0;
        currentIndex = 0;
        invalidate();

        if (contentSize > 1) {
            initAnimator();
            animator.start();
        }

    }

    public void resetContent() {
        if (lists == null || lists.size() == 1)
            return;

        if (animator != null) {
            animator.removeAllListeners();
            animator.cancel();
            animator.end();
            animator = null;
        }

        currentAnimatedValue = 0;
        invalidate();
        initAnimator();
        animator.start();
    }

    /**
     * 主要用来调整TextView的高度
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);
        calcul();

    }

    private void calcul() {
        /* 计算最大文字size */
        if (singleLine) {
            float maxSize = maxTextSize;
            mPaint.setTextSize(maxSize);

            for (int i = 0; i < lists.size(); i++) {
                if (mPaint.measureText(lists.get(i)) > mPaint.measureText(maxLenStr))
                    maxLenStr = lists.get(i);
            }

            while (mPaint.measureText(maxLenStr) > mWidth) {
                maxSize -= 1;
                mPaint.setTextSize(maxSize);
            }
        }

        Rect bounds = new Rect();
        if (contentSize <= 0) {
            return;
        }
        String text = lists.get(0);
        mPaint.getTextBounds(text, 0, text.length(), bounds);

        paddingLeft = getPaddingLeft();

        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        //计算文字高度
        fontHeight = fontMetrics.bottom - fontMetrics.top;
        fontLeading = fontMetrics.leading;

        //计算文字的baseline
        textBaseY = mHeight - (mHeight - fontHeight) / 2 - fontMetrics.bottom;
        textBaseY2 = mHeight - (mHeight - 2 * fontHeight - fontLeading) / 2 - fontHeight - fontLeading - fontMetrics.bottom;

        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (contentSize <= 0) {
            return;
        }

        //直接使用mHeight控制文本绘制，会因为text的baseline的问题不能居中显示
        int verticalOffset = Math.round(2 * textBaseY * (0.5f - currentAnimatedValue));
        int verticalOffset2 = Math.round(textBaseY2 - 2 * currentAnimatedValue * (fontHeight + fontLeading + textBaseY2));

        if (singleLine) {
            //文本自动换行
            if (switchOrientation == 0) {//向上滚动切换
                if (verticalOffset > 0) {
                    canvas.drawText(outStr, paddingLeft, verticalOffset, mPaint);
                } else {
                    canvas.drawText(inStr, paddingLeft, 2 * textBaseY + verticalOffset, mPaint);
                }
            } else {
                if (verticalOffset > 0) {//向下滚动切换,暂时未计算
                    canvas.drawText(outStr, paddingLeft, 2 * textBaseY - verticalOffset, mPaint);
                } else {
                    canvas.drawText(inStr, paddingLeft, -verticalOffset, mPaint);
                }
            }
        } else {
            //文本自动换行
            if (switchOrientation == 0) {//向上滚动切换
                if (verticalOffset > 0) {
                    String[] texts = autoSplit(outStr, mPaint, mWidth);
                    if (texts.length > 1) {
                        for (String text : texts) {
                            canvas.drawText(text, paddingLeft, verticalOffset2, mPaint);  //坐标以控件左上角为原点
                            verticalOffset2 += fontHeight + fontLeading; //添加字体行间距
                        }
                    } else {
                        canvas.drawText(outStr, paddingLeft, verticalOffset, mPaint);
                    }
                } else {
                    String[] texts = autoSplit(inStr, mPaint, mWidth);
                    if (texts.length > 1) {
                        for (String text : texts) {
                            canvas.drawText(text, paddingLeft, verticalOffset2 + 2 * (fontHeight + fontLeading + textBaseY2), mPaint);  //坐标以控件左上角为原点
                            verticalOffset2 += fontHeight + fontLeading; //添加字体行间距
                        }
                    } else {
                        canvas.drawText(inStr, paddingLeft, 2 * textBaseY + verticalOffset, mPaint);
                    }
                }
            } else {
                if (verticalOffset > 0) {//向下滚动切换,暂时未计算
                    canvas.drawText(outStr, paddingLeft, 2 * textBaseY - verticalOffset, mPaint);
                } else {
                    canvas.drawText(inStr, paddingLeft, -verticalOffset, mPaint);
                }
            }
        }

    }

    /* 换行规则，as you like 这里只对需要换行时在第一个数字处换行 */
    private String[] autoSplit(String content, Paint p, float width) {
        float textWidth = p.measureText(content);
        if (textWidth <= width) {
            return new String[]{content};
        }

        String[] lineTexts = new String[2];
        for (int i = 0; i < content.length(); i++) {
            if (StringUtils.isFigure(content.substring(i, i + 1))) {
                lineTexts[0] = content.substring(0, i);
                lineTexts[1] = content.substring(i, content.length());
                if (lineTexts[1] == null)
                    return new String[]{content};

                return lineTexts;
            }

        }

//        int start = 0, end = 1, i = 0;
//        int lines = (int) Math.ceil(textWidth / width); //计算行数
//        String[] lineTexts = new String[lines];
//        while (start < length) {
//            if (p.measureText(content, start, end) > width) { //文本宽度超出控件宽度时
//
//
//                lineTexts[i++] = (String) content.subSequence(start, end);
//                start = end;
//            }
//            if (end == length) { //不足一行的文本
//                lineTexts[i] = (String) content.subSequence(start, end);
//                break;
//            }
//            end += 1;
//        }
        return new String[]{content};

    }

    @Override
    public void onClick(View v) {
        if (contentSize > currentIndex) {
            if (cbInterface != null) {
                cbInterface.onItemClick(currentIndex);
            }
        }
    }

    //回调接口，用来通知调用者控件当前的状态,index表示开始显示哪一个文本内容
    public interface VerticalSwitchTextViewCbInterface {
        void showNext(int index);

        void onItemClick(int index);
    }

    public void setCbInterface(VerticalSwitchTextViewCbInterface cb) {
        cbInterface = cb;
    }

    private boolean isEquale(List<String> strings) {
        if (lists == null)
            return false;

        if (lists.size() != strings.size())
            return false;

        for (int i = 0; i < strings.size(); i++) {
            if (lists.get(i).equals(strings.get(i)))
                continue;
            else
                return false;
        }

        return true;
    }
}
